package com.mspbots.sync.wise.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.sync.BaseGenericService;
import com.mspbots.sync.model.ExceptionLog;
import com.mspbots.sync.utils.WiseParamsUtils;
import com.mspbots.sync.wise.client.ClientProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import reactor.core.publisher.Flux;

/**
 * com.mspbots.sync.wise.service.SubdataService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2020/3/10
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class SubdataService extends BaseGenericService {


    public Flux<JsonNode> getCompanyStatus(ClientProperties configuration) {
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return this.cwWebClient.fetch("/company/companies/statuses", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync companies statuses error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .msg("Connect wise sync company statuses entry error.")
                                .status(500).type("SYNC-COMPANIES-STATUSES")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    ObjectNode entryNode = jsonNode.deepCopy();
                    entryNode.put("tenantId", configuration.getTenantId());
                    entryNode.put("subDataType", "COMPANY-STATUS");
                    return Flux.just(entryNode);
                });
    }

    public Flux<JsonNode> getScheduleStatuses(ClientProperties configuration) {
        log.debug("This tenant {} get sync connect wise Schedule Statuses start.", configuration.getTenantId());
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return this.cwWebClient.fetch("/schedule/statuses", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync Schedule Statuses error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-SCHEDULE-STATUSES")
                                .msg("Connect wise sync Schedule Statuses entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    ObjectNode entryNode = jsonNode.deepCopy();
                    entryNode.put("tenantId", configuration.getTenantId());
                    entryNode.put("subDataType", "SCHEDULE-STATUS");
                    return Flux.just(entryNode);
                });
    }

    public Flux<JsonNode> getCompanyTeamRoles(ClientProperties configuration) {
        log.debug("This tenant {} get sync connect wise COMPANY-TEAM-ROLES start.", configuration.getTenantId());
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return this.cwWebClient.fetch("/company/teamRoles", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync COMPANY-TEAM-ROLES error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-COMPANY-TEAM-ROLES")
                                .msg("Connect wise sync COMPANY-TEAM-ROLES entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    ObjectNode entryNode = jsonNode.deepCopy();
                    entryNode.put("tenantId", configuration.getTenantId());
                    entryNode.put("subDataType", "COMPANY-TEAM-ROLES");
                    return Flux.just(entryNode);
                });
    }

    public Flux<JsonNode> getTimeZoneSetups(ClientProperties configuration) {
        log.debug("This tenant {} get sync connect wise time zone setups start.", configuration.getTenantId());
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return this.cwWebClient.fetch("/system/timeZoneSetups", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync SYNC-WISE-TIME-ZONE-SETUPS error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-TIME-ZONE-SETUPS")
                                .msg("Connect wise sync SYNC-WISE-TIME-ZONE-SETUPS entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    ObjectNode entryNode = jsonNode.deepCopy();
                    entryNode.put("tenantId", configuration.getTenantId());
                    entryNode.put("subDataType", "TIME-ZONE-SETUPS");
                    return Flux.just(entryNode);
                });
    }


    public Flux<JsonNode> getScheduleCalendars(ClientProperties configuration) {
        log.debug("This tenant {} get sync connect wise schedule Calendars start.", configuration.getTenantId());
        MultiValueMap<String, String> params = WiseParamsUtils.paginationBuild("1", null);
        return this.cwWebClient.fetch("/schedule/calendars", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync SYNC-WISE-SCHEDULE-CALENDARS error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-SCHEDULE-CALENDARS")
                                .msg("Connect wise sync SYNC-WISE-SCHEDULE-CALENDARS entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    ObjectNode entryNode = jsonNode.deepCopy();
                    entryNode.put("tenantId", configuration.getTenantId());
                    entryNode.put("subDataType", "SCHEDULE-CALENDARS");
                    return Flux.just(entryNode);
                });
    }
}
